/* Copyrights Security Engineering Research Group 
 * Author: Nauman (http://recluze.wordpress.com) 
 * 
 */

package edu.serg.mbar.frontend;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

import edu.serg.mbar.ucon.AttributeManager;
import edu.serg.mbar.ucon.AuthenticationFailedException;
import edu.serg.mbar.ucon.AuthenticationManager;
import edu.serg.mbar.ucon.pdp.ExpressionEvaluationManager;
import edu.serg.mbar.ucon.ContextManager;
import edu.serg.mbar.ucon.InvalidSubjectInfoException;
import edu.serg.mbar.ucon.meta.RegisteredStrings;
import edu.serg.mbar.ucon.pdp.AccessManager;
import edu.serg.mbar.ucon.pdp.PolicyEvaluationManager;
import edu.serg.mbar.ucon.pdp.AccessManagerConfigurationException;
import edu.serg.mbar.ucon.pep.PrimitiveActionsManager;
import edu.serg.utils.*;

/**
 * A simple console frontend for the UCON engine.
 * 
 * @author Nauman (recluze.wordpress.com)
 * 
 */
public class ConsoleFrontEnd {

	static Logger log = Logger.getLogger(ConsoleFrontEnd.class);

	public static void main(String args[])
			throws AccessManagerConfigurationException {
		long startTime=System.currentTimeMillis();
		PropertyConfigurator.configure("meta/log4j.properties");
		log.debug("Start Execution");
		log.debug("Initialized the log4j library.");
		
////=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x
//		try
//		{
//		XMLUtils xmlUtils = new XMLUtils();
//		
//		String filename = RegisteredStrings.SUBJECTS_DIR + "imran001.xml";
//		log.debug("Using XPath to read the subject information from file: "
//				+ filename);
//
//		String testxpath = "//sub:Subject/obj:Attributes";
////		String testxpath = "//sub:Subject[sub:ObjectID\text()='imran001']/sub:Attributes";
//		
//		NodeList test = xmlUtils.xPathEvaluateToNodeList(xmlUtils.parseXmlFromFile(filename), testxpath);
////		log.debug("***"+ test.getLength());
////		log.debug((String) test.item(0).getNodeValue());
//		log.debug("The Number of Nodes retrieved is =" + test.getLength());
//		for (int i =0; i<test.getLength();i++){
//			
//		
//		log.debug("The name of the Node is " + test.item(i).getNodeName());
//		log.debug("The value of the Node is " + test.item(i).getNodeValue());
//		xmlUtils.xmlFromNodetoString(test.item(i));
//		}
//		
//		}
//		catch (Exception e)
//		{
//			log.error(e.getMessage());
//		}
//		
//		//=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x=x
						
		AuthenticationManager am = null;
		//Map<String, Vector<String>> attribMap = null;
		try {
			am = new AuthenticationManager();
			//attribMap = am.authenticate("imran001", "TopTopTopSecret");
			am.authenticate("imran001", "TopTopTopSecret");
			log.debug("Authentication successful");//. Received attributes.");
		} catch (AuthenticationFailedException e) {
			log.error("Authentication failed. Quitting.");
			return;
		}

		ContextManager cm = new ContextManager();
		cm.start();

//		try {
//			cm.addSubject(attribMap);
//		} catch (InvalidSubjectInfoException e) {
//			log.error("Invalid subject information. Quitting");
//			return;
//		}

		am = null;
		//attribMap = null;
		try {
			am = new AuthenticationManager();
			//attribMap = am.authenticate("kamran001", "TopSecret");
			am.authenticate("kamran001", "TopSecret");
//			log.debug("Authentication successful. Received attributes.");
		} catch (AuthenticationFailedException e) {
			log.error("Authentication failed. Quitting.");
			return;
		}

//		try {
//			cm.addSubject(attribMap);
//		} catch (InvalidSubjectInfoException e) {
//			log.error("Invalid subject information. Quitting");
//			return;
//		}

		// subject(s) created.
		
		
		log.info("Creating an AttributeManager");
		AttributeManager atManager = new AttributeManager();
		log.info("Creating instance of the Expression Evaluator and assigning an attribute reader to it");
		ExpressionEvaluationManager exprEvaluator = new ExpressionEvaluationManager(atManager);
		
		PolicyEvaluationManager plcEvaluationManager = new PolicyEvaluationManager(atManager, atManager, exprEvaluator);
		PrimitiveActionsManager prmActionsManager = new PrimitiveActionsManager(atManager, atManager, exprEvaluator);
		// Create an AccessManager only when a ContextManager requests an object
		log.info("Creating an AccessManager");
		AccessManager acManager = new AccessManager(plcEvaluationManager, prmActionsManager);
		acManager.addDecisionEventListener(cm);
		
		
		acManager.addMutabilityEventListener(atManager);
//		acManager.assignAttributeReader(atManager);
		
////		Testing update of attributes
//		Vector<Object> attributeValue= new Vector<Object>();
//		attributeValue.add((Object) "Imran");
//		atManager.updateAttributeValue("imran001", "Name", attributeValue);
		// acManager.test();
//		String obj1 = "sampledata/objs/obj1";
//		log.info("Requesting an object : " + obj1 + " for subject nauman");
		log.info("Requesting an Object 'BudgetDoc' for Subjec 'imran001'");
		acManager.requestObject("imran001", "BudgetDoc", "Read");
		
		
//		===================================================
		long finishTime=System.currentTimeMillis();
		SimpleDateFormat dateFormat =new SimpleDateFormat("HH:mm:ss.SSS");
		dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
		log.info("* --> * Elapsed Time: Execution completed in [" + (dateFormat.format(new Date((finishTime -startTime)))) + "] Time");
	}
}
